package appllo5;

import java.beans.PropertyVetoException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class Server2111 {

	static Logger logger = Logger.getLogger("Server.class");

	static final Map<String, SocketChannel> socketmps = new ConcurrentHashMap<String, SocketChannel>();
	static final Map<String, Long> socket_timestrap = new ConcurrentHashMap<String, Long>();
	static final Map<String, LinkedBlockingQueue<String>> rtmsg = new ConcurrentHashMap<String, LinkedBlockingQueue<String>>();
	static final String DB_URL = "";
	static final String USER = "";
	static final String PASS = "";
	static final ComboPooledDataSource ds = new ComboPooledDataSource();
	static final int InorgDistance = 50;

	static {
		ds.setJdbcUrl(DB_URL);
		ds.setUser(USER);
		ds.setPassword(PASS);
		try {
			ds.setDriverClass("com.mysql.cj.jdbc.Driver");
		} catch (PropertyVetoException e) {
			e.printStackTrace();
			logger.log(Level.INFO, e.getMessage());
		}
		ds.setAcquireIncrement(5);
		ds.setInitialPoolSize(10);
		ds.setMinPoolSize(2);
		ds.setMaxPoolSize(100);
	}

	public static void handleDeviceData(SocketChannel socket) throws IOException, SQLException, InterruptedException {

		socket.configureBlocking(false);
		ByteBuffer bf;
		StringBuffer sbReturn = new StringBuffer();
		StringBuffer wifiStr = new StringBuffer();
		StringBuffer wifiInfo = new StringBuffer();
		String strReturn, weixinReturn, url, sql_select_last_data, last_latitude, last_longitude, deviceImei, returnstr,
				rtdataTrim, sql_insert_data, sql_device_conn, deviceData, sql_insert_connect_data;
		String[] dataArr, dataArr1, returnArr, dataarr;
		Connection conn = null;
		PreparedStatement ps_update_device, ps_update_device_conn, ps, ps_select_last_data,
				ps_update_device_no_location, ps_device_connect, ps_select_connect_info;
		ResultSet rs_last_data = null;
		Boolean is_save_data, is_device_coon_flag;
		int device_data_id = 0, slen;
		Double l_lat, l_log, n_lat, n_log, distance;
		byte[] reseiveBytes;
		while (true) {
			ByteBuffer bytes = ByteBuffer.allocate(512);
			if ((socket.read(bytes)) != -1) {
				deviceData = decode(bytes).trim();
				if (deviceData.equals("")) {
					continue;
				}
				logger.log(Level.INFO, "server:" + deviceData);
				if (deviceData.endsWith("]") && deviceData.startsWith("[")) {
					dataArr1 = deviceData.split("\\]\\[");
					for (int ii = 0; ii < dataArr1.length; ii++) {
						deviceData = dataArr1[ii];

						dataArr = deviceData.split("\\*");
						deviceImei = dataArr[1];
						if (deviceImei.length() != 15) {
							socket.close();
							return;
						}
						Server.socketmps.put(deviceImei, socket);
						Server.socket_timestrap.put(deviceImei, System.currentTimeMillis());
						is_device_coon_flag = false;
						if (dataArr1.length > 1) {
							if (ii == 0) {
								deviceData += "]";
							} else {
								deviceData = "[" + deviceData;
							}
						}
						if ((conn == null) || (conn.isClosed())) {
							conn = ds.getConnection();
						}
						if (deviceData.contains("*LK") || deviceData.contains("*KA")) {
							slen = deviceData.indexOf(",");
							if (slen > 0) {
								returnstr = "[" + deviceData.substring(1, slen) + "]";
							} else {
								returnstr = "[" + deviceData.substring(1);
							}
							returnArr = returnstr.split("\\*");
							returnArr[2] = "0002";
							strReturn = "";
							for (int i = 0; i < returnArr.length; i++) {
								strReturn += returnArr[i];
								if (i < returnArr.length - 1) {
									strReturn += "*";
								}
							}
							ByteBuffer bf1 = ByteBuffer.wrap(strReturn.getBytes());
							socket.write(bf1);
//                            writer.flush();
							is_device_coon_flag = true;
							// 保存设备发送连接数据时间
							ps_select_connect_info = conn
									.prepareStatement("update erxi_device set last_online_time=? where imei=?");
							ps_select_connect_info.setDouble(1, System.currentTimeMillis());
							ps_select_connect_info.setString(2, deviceImei);
							ps_select_connect_info.execute();
							ps_select_connect_info.close();
						}

						// 判断是设备执行指令返回值
						if (deviceData.split(",").length == 1) {
							rtdataTrim = deviceData.substring(1, deviceData.length() - 1);
							dataarr = rtdataTrim.split("\\*");
							if (dataarr[3].equals("LED") || dataarr[3].equals("VOICE")) {
								LinkedBlockingQueue<String> queueMsg = rtmsg.get(deviceImei);
								if (queueMsg != null) {
									queueMsg.put(deviceData);
								} else {
									queueMsg = new LinkedBlockingQueue<String>();
									queueMsg.put(deviceData);
									rtmsg.put(deviceImei, queueMsg);
								}
							}
						}

						if (deviceData.contains("*UD,") || deviceData.contains("*UD2,")
								|| deviceData.contains("*AL,")) {

							if (deviceData.contains("*UD,")) {
								// 给设备返回数据
								slen = deviceData.indexOf(",");
								returnstr = deviceData.substring(1, slen);
								returnArr = returnstr.split("\\*");
								returnArr[2] = "0004";
								sbReturn.setLength(0);
								for (int i = 0; i < returnArr.length; i++) {
									sbReturn.append(returnArr[i]);
									if (i < returnArr.length - 1) {
										sbReturn.append("*");
									}
								}
								strReturn = "[" + sbReturn.toString() + ",1]";
								bf = ByteBuffer.allocate(strReturn.length());
								socket.write(bf.put(strReturn.getBytes()));
//                                writer.flush();
							}

							is_device_coon_flag = true;
							int start = deviceData.indexOf(",");
							deviceData = deviceData.substring(start + 1, deviceData.length() - 1);
							dataArr = deviceData.split(",");
							String date = dataArr[0];
							String time = dataArr[1];
							Boolean isGpgEffect = "A".equals(dataArr[2]) ? true : false; // gps是否有效
							int is_gps = isGpgEffect ? 1 : 0;
							String latitude = dataArr[3];
							String longitude = dataArr[5];
							String speed = dataArr[7];
							String direction = dataArr[8]; // 方向
							String altitude = dataArr[9]; // 海拔
							String satellite = dataArr[10]; // 卫星个数
							String signalIntensity = dataArr[11]; // 信号强度
							String electricQuantity = dataArr[12]; // 电量

							// String stepNumber = dataArr[13]; // 计步数
							// String flippingTimes = dataArr[14]; // 翻转次数
							// String deviceStatus = dataArr[15]; // 终端状态
							if (!isGpgEffect) {
								url = "https://api.map.baidu.com/locapi/v2?key=8EmvLAwzEo88K27y1TN9v8sYsSKuaZyB&src=安帕琦&prod=宠物定位&ver=1.0&trace=false";
								Map<String, String> paramJson = new HashMap<String, String>();
								int base_count = Integer.parseInt(dataArr[16]) - 1;
								String mcc = dataArr[18];
								String mnc = dataArr[19];
								String bts = mcc + "," + mnc + "," + dataArr[20] + "," + dataArr[21] + ","
										+ dataArr[22];
								String nearbts = "";
								String json = "";
								for (int i = 23; i < 23 + base_count * 3; i += 3) {
									if (i > 23) {
										nearbts += ",";
									}
									nearbts += mcc + "," + mnc + "," + dataArr[i] + "," + dataArr[i + 1] + ","
											+ dataArr[i + 2];
								}

								int wifiStart = 23 + base_count * 3;
								int lengthData = dataArr.length;
								if (lengthData > wifiStart + 3) {
									for (int i = wifiStart + 1, j = 0; i < lengthData; i += 3, j++) {
										if (j > 0) {
											wifiInfo.append("|");
										}
										wifiStr.append(dataArr[i + 1] + ",");
										wifiStr.append(dataArr[i + 2]);
										wifiInfo.append(wifiStr);
										wifiStr.setLength(0);
									}
									String macs = wifiInfo.toString();
									wifiInfo.setLength(0);
									url = "http://apilocate.amap.com/position?accesstype=1&imei=" + deviceImei
											+ "&key=ae7676899c4d762b8eade0ebe9d43c15&macs="
											+ URLEncoder.encode(macs, "UTF-8");
								} else {
									url = "http://apilocate.amap.com/position?accesstype=0&cdma=0&imei=" + deviceImei
											+ "&key=ae7676899c4d762b8eade0ebe9d43c15&bts=" + bts + "&nearbts="
											+ nearbts;
								}
								json = sendWeixinMessage(url);
								ObjectMapper mapper = new ObjectMapper();
								Map<?, ?> map = mapper.readValue(json, Map.class);
								LinkedHashMap<?, ?> result = (LinkedHashMap<?, ?>) map.get("result");
								if (result.get("location") != null) {
									String[] location = result.get("location").toString().split(",");
									longitude = location[0];
									latitude = location[1];
								} else {

									String sqlUpdateDeviceNoLocation = "update erxi_device_data set create_time=?,is_gps=?,electricQuantity=?,signalIntensity=?,`date`=?,`time`=? where id=?";
									ps_update_device_no_location = conn.prepareStatement(sqlUpdateDeviceNoLocation);

									ps_update_device_no_location.setDouble(1, System.currentTimeMillis());
									ps_update_device_no_location.setInt(2, is_gps);
									ps_update_device_no_location.setString(3, electricQuantity);
									ps_update_device_no_location.setString(4, signalIntensity);
									ps_update_device_no_location.setString(5, date);
									ps_update_device_no_location.setString(6, time);
									ps_update_device_no_location.setInt(7, device_data_id);
									ps_update_device_no_location.execute(); // 执行sql语句
									ps_update_device_no_location.close();
									continue;
								}
							}
							// 低电量微信通知
							if ((Integer.parseInt(electricQuantity) < 5) || Integer.parseInt(electricQuantity) == 10) {
								url = "https://www.ju2xi.com/user/weixin/electricQuantityInfo?imei=" + deviceImei
										+ "&electricQuantity=" + electricQuantity + "&latitude=" + latitude
										+ "&longtitude=" + longitude;
								sendWeixinMessage(url);
							}
//                            conn = DriverManager.getConnection(DB_URL, USER, PASS);
							Statement stmt = conn.createStatement();
							String sql_check_homeon = "select * from erxi_device where imei='" + deviceImei + "'";
							ResultSet rs = stmt.executeQuery(sql_check_homeon);
							int is_home = 0;
							int at_home = 0;
							double center_latitude = 0d;
							double center_longitude = 0d;
							int range = 0;
//							int device_id = 0;
							while (rs.next()) {
//								device_id = rs.getInt("id");
								is_home = rs.getInt("is_home");
								at_home = rs.getInt("at_home");
								range = rs.getInt("range");
								center_latitude = rs.getDouble("center_latitude");
								center_longitude = rs.getDouble("center_longitude");
								// 打开链接
							}
							stmt.close();
							// 判断是否开启了电子围栏
							if (is_home == 1) {
								if (center_latitude != 0 && center_longitude != 0) {
									distance = getDistance(Double.parseDouble(latitude), Double.parseDouble(longitude),
											center_latitude, center_longitude);
									// System.out.println("distance:"+distance);
									// System.out.println("latitude:"+latitude+"longitude:"+longitude+"center_latitude:"+center_latitude+"center_longitude:"+center_longitude);
									if (range > 0) {
										if (distance >= range) {
											// 宠物离开围栏，开始报警
											at_home = 0;
											url = "https://www.ju2xi.com/user/weixin/getindusinfo?imei=" + deviceImei
													+ "&athome=" + at_home + "&latitude=" + latitude + "&longtitude="
													+ longitude;
											weixinReturn = sendWeixinMessage(url);
//                                        System.out.println("distance:" + distance + ";range:" + range + ";url:" + url + ";weixinReturn:" + weixinReturn);
										}
//                                    if (distance < range) {
//                                    }
									}
								}
							}

							// 计算WiFi定位的误差
//                            double pre_times = System.currentTimeMillis() - 3600 * 3000;
							sql_select_last_data = "select id,latitude,longitude,create_time from erxi_device_data where imei=? order by create_time desc limit 1";
							ps_select_last_data = conn.prepareStatement(sql_select_last_data);
							ps_select_last_data.setString(1, deviceImei);
//                        ps_select_last_data.setDouble(2, pre_times);
							rs_last_data = ps_select_last_data.executeQuery();
							is_save_data = false;
							if (rs_last_data.next()) {
								last_latitude = rs_last_data.getString("latitude");
								last_longitude = rs_last_data.getString("longitude");
								device_data_id = rs_last_data.getInt("id");
								l_lat = Double.parseDouble(last_latitude);
								l_log = Double.parseDouble(last_longitude);
								n_lat = Double.parseDouble(latitude);
								n_log = Double.parseDouble(longitude);
								// 获取设备两次上传坐标的距离
								double distance_no = getDistance(l_lat, l_log, n_lat, n_log);
								// 如果两次坐标的距离大于20米就新增一条，否则视为冗余数据忽略
								if (distance_no > InorgDistance) {
									is_save_data = true;
								}
							} else {
								is_save_data = true;
							}
							ps_select_last_data.close();
							if (is_save_data) {
								sql_insert_data = "insert into erxi_device_data (`imei`,`date`,`time`,latitude,longitude,speed,direction,satellite,altitude,signalIntensity,electricQuantity,create_time,is_gps) values (?,?,?,?,?,?,?,?,?,?,?,?,?)";
								ps = conn.prepareStatement(sql_insert_data);
								ps.setString(1, deviceImei);
								ps.setString(2, date);
								ps.setString(3, time);
								ps.setString(4, latitude);
								ps.setString(5, longitude);
								ps.setString(6, speed);
								ps.setString(7, direction);
								ps.setString(8, satellite);
								ps.setString(9, altitude);
								ps.setString(10, signalIntensity);
								ps.setString(11, electricQuantity);
								ps.setDouble(12, System.currentTimeMillis());
								ps.setInt(13, is_gps);
								ps.execute(); // 执行sql语句
								ps.close();
							} else {
								if (device_data_id != 0) {
									String sqlUpdateDevice = "update erxi_device_data set create_time=?,is_gps=?,electricQuantity=?,signalIntensity=?,`date`=?,`time`=? where id=?";
									ps_update_device = conn.prepareStatement(sqlUpdateDevice);

//                                ps_update_device.setString(1, latitude);
//                                ps_update_device.setString(2, longitude);
									ps_update_device.setDouble(1, System.currentTimeMillis());
									ps_update_device.setInt(2, is_gps);
									ps_update_device.setString(3, electricQuantity);
									ps_update_device.setString(4, signalIntensity);
									ps_update_device.setString(5, date);
									ps_update_device.setString(6, time);
									ps_update_device.setInt(7, device_data_id);
									ps_update_device.execute(); // 执行sql语句
									ps_update_device.close();
								}
							}
						}
						if (is_device_coon_flag) {
//                            Statement stmtUpdateDeviceConn = conn.createStatement();
							sql_device_conn = "update erxi_device set last_online_time=? where imei=?";
							ps_update_device_conn = conn.prepareStatement(sql_device_conn);
							ps_update_device_conn.setLong(1, System.currentTimeMillis());
							ps_update_device_conn.setString(2, deviceImei);
							ps_update_device_conn.execute();
							ps_update_device_conn.close();
						}
						conn.close();
					}
//                    writer = null;
				} else {
					socket.close();
					return;
				}
			}
		}
	}

	public static String sendWeixinMessage(String url) throws ClientProtocolException, IOException {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpGet httpget = new HttpGet(url);
		CloseableHttpResponse response = httpclient.execute(httpget);
		String str = "";
		try {
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				str = EntityUtils.toString(entity);
			}
		} finally {
			response.close();
		}
		return str;
	}

	public static String postJson(String uri, String json, int connectTimeout, int connectionRequestTimeout,
			int socketTimeout) throws IOException, ParseException {
		if (StringUtils.isAnyBlank(uri, json)) {
			return null;
		}

		CloseableHttpClient client = HttpClients.createDefault();
		HttpPost post = new HttpPost(uri);
		// Create request data
		StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
		// Set request body
		post.setEntity(entity);

		RequestConfig config = RequestConfig.custom().setConnectTimeout(connectTimeout)
				.setConnectionRequestTimeout(connectionRequestTimeout).setSocketTimeout(socketTimeout).build();
		post.setConfig(config);
		// Response content
		String responseContent = null;
		CloseableHttpResponse response = null;
		try {
			response = client.execute(post);
			if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				responseContent = EntityUtils.toString(response.getEntity(), Consts.UTF_8.name());
			}
		} finally {
			if (ObjectUtils.anyNotNull(response)) {
				response.close();
			}
			if (ObjectUtils.anyNotNull(client)) {
				client.close();
			}
		}
		return responseContent;
	}

	public static String decode(ByteBuffer buffer) {
		byte[] bt = buffer.array();
		return new String(bt);

	}

	public static void main(String[] args) throws IOException {
		new Thread(new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					// System.out.println(Server.socketmps);
					Set<Map.Entry<String, Long>> set = Server.socket_timestrap.entrySet();
					Iterator<Map.Entry<String, Long>> it = set.iterator();
					long currentTime = System.currentTimeMillis();
					while (it.hasNext()) {
						Map.Entry<String, Long> item = it.next();
						String key = item.getKey();
						Long timestrap = item.getValue();
						if (((currentTime - timestrap)) > 310000) {
							SocketChannel sock = Server.socketmps.get(key);
							if (sock != null) {
								Server.socketmps.remove(key);
							}
						}
					}
					try {
						Thread.sleep(300 * 1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
						logger.log(Level.INFO, e.getMessage());
					}
				}
			}
		})).start();

		new Thread(new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					try {
						LoggerUtil.setLogingProperties(logger);
					} catch (IOException e) {
						e.printStackTrace();
						logger.log(Level.INFO, e.getMessage());
					}
					try {
						Thread.sleep(3600000 * 12);
					} catch (InterruptedException e) {
						e.printStackTrace();
						logger.log(Level.INFO, e.getMessage());
					}
				}
			}
		})).start();

		// 监听设备发送的数据
		new Thread(new Runnable() {
			@Override
			public void run() {
				int port = 8888;
				ServerSocketChannel server = null;
				try {
					SocketAddress local = new InetSocketAddress(port);
					server = ServerSocketChannel.open();
					server.socket().bind(local);
				} catch (IOException e) {
					e.printStackTrace();
					logger.log(Level.INFO, e.getMessage());
				}
				System.out.println("正在监听8888端口");
				while (true) {
					SocketChannel socket = null;
					try {
						socket = server.accept();
						new Thread(new Task(socket)).start();
					} catch (IOException e) {
						e.printStackTrace();
						logger.log(Level.INFO, e.getMessage());
					}
				}
			}
		}).start();

		// 监听客户发送的命令
		new Thread(new Runnable() {
			@SuppressWarnings("resource")
			@Override
			public void run() {
				int port = 8889;
				System.out.println("正在监听8889端口");
				ServerSocket server = null;
				try {
					server = new ServerSocket(port);
				} catch (IOException e) {
					e.printStackTrace();
					logger.log(Level.INFO, e.getMessage());
				}
				while (true) {
					// server尝试接收其他Socket的连接请求，server的accept方法是阻塞式的
					Socket socket = null;
					try {
						socket = server.accept();
					} catch (IOException e) {
						e.printStackTrace();
						logger.log(Level.INFO, e.getMessage());
					}
					// System.out.println("与客户端建立新连接...");
					try {
						new Thread(new ClientCommand(socket)).start();
					} catch (IOException e) {
						e.printStackTrace();
						logger.log(Level.INFO, e.getMessage());
					}
				}
			}
		}).start();
	}

	/**
	 * 处理Socket请求的线程类
	 */
	static class Task implements Runnable {

		private SocketChannel socket;

		public Task(SocketChannel socket) throws IOException {
			// System.out.println("socket:" + socket.getPort());
			this.socket = socket;
		}

		@Override
		public void run() {
			try {
				Server.handleDeviceData(socket);
				socket.close();
			} catch (Exception e) {
				e.printStackTrace();
				logger.log(Level.INFO, e.getMessage());
			}
		}

	}

	/**
	 * 处理Socket请求的线程类
	 */
	static class ClientCommand implements Runnable {

		private Socket socket;

		public ClientCommand(Socket socket) throws IOException {
			// System.out.println("socket:" + socket.getPort());
			this.socket = socket;
		}

		@Override
		public void run() {
			OutputStream writer = null;
			String s = "false\n";
			InputStream is = null;
			ByteBuffer bt3;
			String cmdLength, str_cmd;
			int int_cmd;
			byte[] chars = new byte[10240];
			try {
				is = socket.getInputStream();
//                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
				writer = socket.getOutputStream();
//                int int_cmd = br.read(chars,0,20480);

				int_cmd = is.read(chars);

				str_cmd = new String(chars, 0, int_cmd);
				String[] commandarr = str_cmd.split("&&");
				String imei = commandarr[0];
//                System.out.println(socketmps);
//                System.out.println(socketDevice);
				SocketChannel socketDevice = Server.socketmps.get(imei);
				if (socketDevice != null) {
//                    BufferedReader brDevice = new BufferedReader(
//                            new InputStreamReader(socketDevice.getInputStream(), "UTF-8"));
//                    InputStreamReader input = new InputStreamReader(socket.getInputStream(), "UTF-8");

//                    OutputStream writerDevice = socketDevice.getOutputStream();
					String[] cmd = commandarr[1].split("\\*");
					String coomandServer = "";
					String cmdHead;
					if (cmd[0].equals("uploadamr")) {
						String cmds = null;
						String fileName = cmd[1].trim();
						File file = new File(fileName);
						@SuppressWarnings("resource")
						InputStream in = new FileInputStream(file);
						byte[] tempbytes = new byte[10240];
						int byteread = in.read(tempbytes);
//						while ((byteread = ) != -1) {
//						}
						cmds = "[SR*" + imei + "*" + Integer.toHexString(byteread + 3) + "*TK,";
						String a = "]";
						byte[] bt1 = cmds.getBytes();
						byte[] bt2 = a.getBytes();
						int tl = bt1.length + bt2.length + byteread;
//                        byte[] bt3 = new byte[tl];
						bt3 = ByteBuffer.allocate(tl);

						for (int i = 0; i < bt1.length; i++) {
//                            bt3[i] = bt1[i];
							bt3.put(bt1);
						}

						for (int i = 0; i < byteread; i++) {
							int j = i + bt1.length;
//                            bt3[j] = tempbytes[i];
							bt3.put(tempbytes[i]);
						}

						for (int i = 0; i < bt2.length; i++) {
							int j = i + bt1.length + byteread;
//                            bt3[j] = bt2[i];
							bt3.put(bt2[i]);
						}
						socketDevice.write(bt3);
//                        socketDevice.flush();
						// byte转字符串
						Charset charset = Charset.defaultCharset();
//                        ByteBuffer buf = ByteBuffer.wrap(bt3);
						CharBuffer cBuf = charset.decode(bt3);

						logger.log(Level.INFO, "client:" + cBuf);
						file.delete();
						s = "ok\n";
					} else {

						cmdLength = Integer.toHexString(cmd[3].trim().length() - 1);
						int intLeng = cmdLength.length();
						if (cmd.length == 4) {
							int de = 4 - intLeng;
							for (int i = 0; i < de; i++) {
								coomandServer += "0";
							}
							cmd[2] = coomandServer + cmdLength;
						}
						socketDevice.write(ByteBuffer.wrap(StringUtils.join(cmd, '*').getBytes()));
//                        writerDevice.flush();
						logger.log(Level.INFO, "client:" + StringUtils.join(cmd, '*'));

						String[] cmdHeadArr = commandarr[1].split(",");
						cmdHead = cmdHeadArr[0];
						cmdHead = cmdHead.split("\\*")[3];
						int c = 0;
						if (cmdHead.equals("LED") || cmdHead.equals("VOICE")) {
							while (true) {
								LinkedBlockingQueue<String> queueMsg = rtmsg.get(imei);
								c++;
								if (queueMsg != null) {
									String strMsg = queueMsg.poll();
									if (strMsg != null) {
										strMsg = strMsg.substring(1, strMsg.length() - 1);
										String[] arrMsg = strMsg.split("\\*");
										strMsg = arrMsg[3];
										if (strMsg.equals(cmdHead)) {
											s = "ok\n";
											break;
										}
									}
								}
								if (c >= 10) {
									s = "false\n";
									break;
								}
								Thread.sleep(1000);
							}
						} else {
							s = "ok\n";
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				logger.log(Level.INFO, e.getMessage());
			} finally {
				try {
					writer.write(s.getBytes());
					writer.flush();
					is.close();
					writer.close();
					socket.close();
				} catch (IOException e) {
					logger.log(Level.INFO, e.getMessage());
					e.printStackTrace();
				}
			}
		}

		// private void handlerSocket() throws Exception {
		//
		// }
	}

	@SuppressWarnings("finally")
	public static boolean checkSocketAlivle(Socket socket) {
		Boolean flag = false;
		try {
			socket.sendUrgentData(0);
			logger.log(Level.INFO, "++++++++++++++++++++++++++send connetction message+++++++++++++++");
			flag = true;
			return flag;
		} catch (IOException e) {
			flag = false;
			try {
				socket.close();
			} catch (IOException e1) {
				e1.printStackTrace();
				logger.log(Level.INFO, e1.getMessage());
			}
			e.printStackTrace();
			logger.log(Level.INFO, e.getMessage());
		} finally {
			return flag;
		}

	}

	private static double EARTH_RADIUS = 6378.137;

	private static double rad(double d) {
		return d * Math.PI / 180.0;
	}

	/**
	 * 通过经纬度获取距离(单位：米)
	 *
	 * @param lat1
	 * @param lng1
	 * @param lat2
	 * @param lng2
	 * @return
	 */
	public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
		double radLat1 = rad(lat1);
		double radLat2 = rad(lat2);
		double a = radLat1 - radLat2;
		double b = rad(lng1) - rad(lng2);
		double s = 2 * Math.asin(Math.sqrt(
				Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
		s = s * EARTH_RADIUS;
		s = Math.round(s * 10000d) / 10000d;
		s = s * 1000;
		return s;
	}

}
